#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "app_proxy.h"
#include "sm_trace.h"
#include "sm_kapi.h"
#include "xmsg.h"
#include "itc.h"
#include "mmi.h"



int ai_on_application_information_display(char* menuText);
void SetMenuDisplay(char* menuText);
void openMenuMMI(menu_t *pmenu);

typedef struct
{
	unsigned char 	m_application_type;
	unsigned short 	m_application_manufacture;
	unsigned short	m_manufacture_code;
	unsigned char 	m_mainmenu[256];
}application_information_t;

#define AI_SESSION_COUNT		8
typedef struct
{
	unsigned char 				m_isUsed;
	short 						m_ssnb;
	unsigned char 				m_isAppInfoValid;
	application_information_t 	m_appInfo;
}ai_session_table_t;

static ai_session_table_t s_ai_tab_session[AI_SESSION_COUNT];


int ai_init(void)
{
	int i;

	SM_TRACE_ENTRY(TRMOD_APP, "ai_init() - entry\r\n");

	for(i=0;i<AI_SESSION_COUNT; i++)
		s_ai_tab_session[i].m_isUsed=0;

	SM_TRACE_RETURN(TRMOD_APP, "ai_init() - return 0\r\n");
	return 0;
}

void ai_on_application_information_changed(unsigned long flag)
{
	//this function should be implemented by other parts of host software
	SM_TRACE_INFO(TRMOD_APP,"Application information changed\r\n");
}


int ai_on_message(xmsg_t* pXmsg)
{
	int 			i, j;
	unsigned short 	ssnb;
	unsigned char 	tcid;
	xmsg_t			xmsg;

	//SM_ASSERT(pXmsg);

	SM_TRACE_ENTRY(TRMOD_APP, "ai_on_message() - entry,pXmsg=0x%08X\r\n", pXmsg);

	SM_TRACE_INFO(TRMOD_APP, "ai_on_message() - %s(0x%02X) received\r\n",
				XMSG_NAME(pXmsg->m_type),pXmsg->m_type);

	switch(pXmsg->m_type)
	{
	case APP_OPEN_SS_REQ:
		ssnb = pXmsg->m_bd.m_app_open_ss_req.m_ssnb;
		tcid = pXmsg->m_bd.m_app_open_ss_req.m_tcid;
		SM_TRACE_INFO(TRMOD_APP, "ai_on_message() - APP_OPEN_SS_REQ received, ssnb=%d\r\n", ssnb);

		for(i=0;i<AI_SESSION_COUNT;i++)
		{
			if(!s_ai_tab_session[i].m_isUsed)
				break;
		}

		memset(&xmsg, 0x00, sizeof(xmsg));
		xmsg.m_sndrcver = (RM << 4) | RM;
		xmsg.m_type  = APP_OPEN_SS_RSP;
		xmsg.m_bd.m_app_open_ss_rsp.m_tcid = tcid;
		xmsg.m_bd.m_app_open_ss_rsp.m_ssnb = ssnb;
		xmsg.m_bd.m_app_open_ss_rsp.m_ressId = pXmsg->m_bd.m_app_open_ss_req.m_ressId;
		if(i<AI_SESSION_COUNT)
		{
			//item has been used, but app_info not valid yet.
			//app_info will be filled when application_info is received.
			s_ai_tab_session[i].m_isUsed=1;
			s_ai_tab_session[i].m_ssnb=ssnb;
			s_ai_tab_session[i].m_isAppInfoValid=0;
			xmsg.m_bd.m_app_open_ss_rsp.m_status = SS_OK;
		}
		else
		{
			//session can't be opened, resource exists but unavailable
			xmsg.m_bd.m_app_open_ss_rsp.m_status = SS_NOTAVAILABLE;
		}

		SM_TRACE_INFO(TRMOD_APP, "ai_on_message() - will send APP_OPEN_SS_RSP to PROXY\r\n");
		ITC_SendXmsg(&xmsg);
		break;

	case APP_SS_OPENED:
		ssnb=pXmsg->m_bd.m_app_ss_opened.m_ssnb;
		SM_TRACE_INFO(TRMOD_APP, "ai_on_message() - APP_SS_OPENED received,ssnb=%d\r\n",ssnb);

		for(i=0;i<AI_SESSION_COUNT;i++)
		{
			if((s_ai_tab_session[i].m_isUsed)&&(s_ai_tab_session[i].m_ssnb==ssnb))
				break;
		}
		if(i<AI_SESSION_COUNT)
		{
			SM_TRACE_INFO(TRMOD_APP,"ai_on_message() - send application_info_enq, ssnb: %d\r\n", ssnb);
			send_app_apdu_to_proxy(ssnb, CI_APDU_TAG_APPLICATION_INFO_ENG, NULL, 0);
		}
		break;

	case APP_SS_BROKEN:
		ssnb=pXmsg->m_bd.m_app_ss_broken.m_ssnb;
		for(i=0;i<AI_SESSION_COUNT;i++)
		{
			if((s_ai_tab_session[i].m_isUsed) && (s_ai_tab_session[i].m_ssnb==ssnb))
			{
				break;
			}
		}
		if(i<AI_SESSION_COUNT)
		{
			s_ai_tab_session[i].m_isUsed=0;
			ai_on_application_information_changed(APP_SS_BROKEN);
		}
		break;

	case APP_TMPEND:
		ssnb = (unsigned short)pXmsg->m_bd.m_timer.m_param;
		SM_TRACE_INFO(TRMOD_APP,"ai_on_message() - is timer event, send enter_menu, ssnb: %d\r\n", ssnb);
		send_app_apdu_to_proxy(ssnb, CI_APDU_TAG_ENTER_MENU, NULL, 0); //enter menu
		break;

	case APP_APDU:
	{
		unsigned long 	apduTag;
		unsigned long 	bodyLen;
		long 			totalLen;
		unsigned char* 	pbBody = NULL;
		unsigned char* 	pbApdu = NULL;

		totalLen=pXmsg->m_bd.m_app_apdu.m_apduLen;
		ssnb=pXmsg->m_bd.m_app_apdu.m_ssnb;
		pbApdu = pXmsg->m_bd.m_app_apdu.m_pbApdu;
		for(;totalLen>0;)
		{
			pbBody=decode_apdu(pbApdu, &apduTag, &bodyLen);
			totalLen = totalLen-(((unsigned long)pbBody)-((unsigned long)pbApdu)) - bodyLen;
			pbApdu = pbBody+bodyLen;//point to the next apdu
			if(totalLen<0)
			{
				SM_TRACE_ERROR(TRMOD_APP,"ai_on_message() - bodyLen error in apdu\r\n");
				break;
			}
			switch(apduTag)
			{
			case CI_APDU_TAG_APPLICATION_INFO://application info
				for(i=0;i<AI_SESSION_COUNT;i++)
				{
					if((s_ai_tab_session[i].m_isUsed)&&(s_ai_tab_session[i].m_ssnb==ssnb))
						break;
				}
				if(i<AI_SESSION_COUNT)
				{
					s_ai_tab_session[i].m_isAppInfoValid=1;
					s_ai_tab_session[i].m_appInfo.m_application_type=pbBody[0];
					s_ai_tab_session[i].m_appInfo.m_application_manufacture=pbBody[1]*256+pbBody[2];
					s_ai_tab_session[i].m_appInfo.m_manufacture_code=pbBody[3]*256+pbBody[4];
					for(j=0;j<pbBody[5];j++)
						s_ai_tab_session[i].m_appInfo.m_mainmenu[j]=pbBody[6+j];
					s_ai_tab_session[i].m_appInfo.m_mainmenu[j] = 0;

					//Add by Zet
					//display the ai in menu
					ai_on_application_information_display(s_ai_tab_session[i].m_appInfo.m_mainmenu);

					ai_on_application_information_changed(apduTag);
					
//					SM_TRACE_INFO(TRMOD_APP,"ai_on_message() - set enter_menu timer, 10 seconds\r\n");
//					ITC_SetTimerEx(TMID_APP_ENTERMENU, 12000, ssnb);
				}
				break;
			default:
				SM_TRACE_ERROR(TRMOD_APP,"ai_on_message() - unkown apdu apduTag=0x%06X\r\n", apduTag);
				break;
			} //end swith
		} // end for
		break;
	}

	default:
		SM_TRACE_ERROR(TRMOD_APP,"ai_on_message() - unkown mess type=0x%02X\r\n", pXmsg->m_type);
		break;
	}

	SM_TRACE_RETURN(TRMOD_APP, "ai_on_message() - return 0\r\n");
	return 0;
}


int ai_enter_menu (unsigned char appIndex)
{
	//interfact to other software in the host
	int i, 			validIndex;
	unsigned short	ssnb;

	SM_TRACE_ENTRY(TRMOD_APP, "ai_enter_menu() - entry,appIndex=0x%08X\r\n", appIndex);

	validIndex=-1;
	for (i = 0; i < AI_SESSION_COUNT; i++)
	{
		if(s_ai_tab_session[i].m_isUsed && s_ai_tab_session[i].m_isAppInfoValid)
		{
			validIndex++;
			if (appIndex == validIndex)
			{
				ssnb = s_ai_tab_session[i].m_ssnb;
				SM_TRACE_INFO(TRMOD_APP,"ai_enter_menu() - send enter_menu, ssnb: %d\r\n", ssnb);
				send_app_apdu_to_proxy(ssnb, CI_APDU_TAG_ENTER_MENU, NULL, 0); //enter menu

				break;
			}
		}
	}

	SM_TRACE_RETURN(TRMOD_APP, "ai_enter_menu() - return\r\n");

	return validIndex;
}

int ai_on_application_information_display(char* menuText)
{
//	SetMenuDisplay(menuText);
	return 1;
}
